package service

import (
	"bufio"
	"echo-utils/global"
	"io"
	"os"
	"path/filepath"
	"strings"
)

type EchoFile struct {
	iniName   string   //配置文件名称
	imageName string   //项目介绍图片目录名称
	iniList   []string //所有遍历到的配置文件

	imageList     []string //图片列表，遍历项目图片目录下图片所得
	serverImgPath string   //系统中保存图片的路径
}

// 遍历函数，获得符合条件的配置文件列表
func (e *EchoFile) findIni(path string, info os.FileInfo, err error) error {
	filePart := strings.Split(path, "\\")
	if len(filePart) < 1 {
		return nil
	}
	fileName := filePart[len(filePart)-1]
	if fileName == e.iniName {
		e.iniList = append(e.iniList, path)
	}
	return nil
}

// 遍历函数，获得介绍图片列表
func (e *EchoFile) findThumbs(path string, info os.FileInfo, err error) error {
	filePart := strings.Split(path, ".")
	if len(filePart) < 1 {
		return nil
	}
	fileExt := filePart[len(filePart)-1]
	if fileExt == "png" || fileExt == "jpg" {
		e.imageList = append(e.imageList, path)
	}
	return nil
}

// 查找资源下介绍图片
func (e *EchoFile) findImages(path string) {
	filepath.Walk(path, e.findThumbs)
}

// 根据配置文件绝对地址，获取配置文件所在目录
func (e *EchoFile) iniPath(ini string) string {
	return strings.Replace(ini, "\\"+e.iniName, "", 1)
}

func (e *EchoFile) PathForIni(ini string) string {
	return e.iniPath(ini)
}

// 根据资源目录，获取介绍图片路径
func (e *EchoFile) imagePath(iniPath string) string {
	return iniPath + "\\" + e.imageName
}

// 按行读取文件，返回每行内容
func (e *EchoFile) ReadLines(path string) ([]string, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	lines := make([]string, 0)
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}
	return lines, scanner.Err()
}

func (e *EchoFile) fileExt(file string) string {
	filePart := strings.Split(file, ".")
	if len(filePart) == 0 {
		return ""
	}
	return filePart[len(filePart)-1]
}

func (e *EchoFile) copyFile(src, dst string) (err error) {
	fi, err := os.Open(src)
	if err != nil {
		return
	}

	defer fi.Close()

	fo, err := os.Create(dst)
	if err != nil {
		return
	}

	defer func() {
		if errFo := fo.Close(); errFo != nil {
			err = errFo
		}
	}()

	_, err = io.Copy(fo, fi)
	if err != nil {
		return
	}

	fiStat, err := fi.Stat()
	if err != nil {
		return
	}

	err = os.Chmod(dst, fiStat.Mode())
	if err != nil {
		return
	}
	err = os.Chtimes(dst, fiStat.ModTime(), fiStat.ModTime())
	if err != nil {
		return
	}

	return
}

// 查找所有配置文件
func (e *EchoFile) FindSource(path string) []string {
	filepath.Walk(path, e.findIni)
	return e.iniList
}

// 判断是否是目录
func (e *EchoFile) IsDir(path string) bool {
	s, err := os.Stat(path)
	if err != nil {
		return false
	}
	return s.IsDir()
}

// 根据配置文件，复制图片到系统中，以便提供http访问
func (e *EchoFile) CopyImage(iniFile string) []string {
	iniPath := e.iniPath(iniFile)
	imgPath := e.imagePath(iniPath)

	newImgs := make([]string, 0)
	//重置imageList，防止在其他地方有对imageList设置过
	e.imageList = make([]string, 0)
	e.findImages(imgPath)
	for _, v := range e.imageList {
		ext := e.fileExt(v)
		if ext == "" {
			continue
		}
		fileName := md5Val(v) + "." + ext
		newFile := e.serverImgPath + "/" + fileName
		err := e.copyFile(v, newFile)
		if err != nil {
			// log.Fatalf("CopyImage err : %v", err)
			global.Logger.Errorf("CopyImage err : %v", err)
			continue
		}
		newImgs = append(newImgs, "/images/"+fileName)
	}
	return newImgs
}

func NewEchoFile() *EchoFile {
	il := make([]string, 0)
	return &EchoFile{
		iniName:       "echo.txt",
		imageName:     "echo-images",
		iniList:       il,
		serverImgPath: global.ProDirectory + "/images",
	}
}
